﻿//using System;
//using Microsoft.Xna.Framework;
//using Microsoft.Xna.Framework.Graphics;
//using Phoenix.Xna.Framework.Components.Cameras;
//using Phoenix.Xna.Framework.FrameworkExtensions;
//using Phoenix.Xna.Framework.Graphics;
//using Phoenix.Xna.Framework.Graphics.Primitives;

//namespace Phoenix.Xna.Framework.Components.Sky
//{
//    public class SkyDomeShader : Shader<SkyDomeShaderState>
//    {
//        private Dome _dome;
//        private float _previousTheta;
//        private float _previousPhi;
//        private DepthStencilBuffer _oldDepthBuffer;
//        private DepthStencilBuffer _newDepthBuffer;
//        private RenderTarget2D _mieTarget;
//        private RenderTarget2D _rayleighTarget;
//        private Vector3 _waveLength;
//        private QuadRenderer _quadRenderer;
//        private QuadRenderer _textureRenderer; 
//        private MoonShader _moonShader;
//        private PerlinCloudsShader _perlinCloudsShader;

//        public Matrix WVP
//        {
//            get { return EffectMap.GetParameter<Matrix>("Render", "WVP"); }
//            set 
//            {
//                EffectMap.SetParameter<Matrix>("Render", "WVP", value); 
//            }
//        }
//        public Matrix World
//        {
//            get { return EffectMap.GetParameter<Matrix>("Render", "World"); }
//            set { EffectMap.SetParameter<Matrix>("Render", "World", value); }
//        }
//        public Matrix View
//        {
//            get { return EffectMap.GetParameter<Matrix>("Render", "View"); }
//            set { EffectMap.SetParameter<Matrix>("Render", "View", value); }
//        }
//        public Matrix Projection
//        {
//            get { return EffectMap.GetParameter<Matrix>("Render", "Projection"); }
//            set { EffectMap.SetParameter<Matrix>("Render", "Projection", value); }
//        }
//        public Vector3 SunlightDirection
//        {
//            get { return EffectMap.GetParameter<Vector3>("Render", "SunlightDirection"); }
//            set
//            {
//                EffectMap.SetParameter<Vector3>("Render", "SunlightDirection", value);
//                EffectMap.SetParameter<Vector3>("Update", "SunlightDirection", value);
//            }
//        }
//        public Vector3 InverseWavelength
//        {
//            get { return EffectMap.GetParameter<Vector3>("Update", "InverseWavelength"); }
//            set { EffectMap.SetParameter<Vector3>("Update", "InverseWavelength", value); }
//        }
//        public Vector3 MieWavelength
//        {
//            get { return EffectMap.GetParameter<Vector3>("Update", "MieWavelength"); }
//            set { EffectMap.SetParameter<Vector3>("Update", "MieWavelength", value); }
//        }
//        public float Exposure
//        {
//            get { return EffectMap.GetParameter<float>("Render", "Exposure"); }
//            set { EffectMap.SetParameter<float>("Render", "Exposure", value); }
//        }
//        public float Samples
//        {
//            get { return EffectMap.GetParameter<float>("Render", "Samples"); }
//            set
//            {
//                EffectMap.SetParameter<float>("Render", "Samples", value);
//                EffectMap.SetParameter<float>("Update", "Samples", value);
//            }
//        }
//        public float StarIntensity
//        {
//            get { return EffectMap.GetParameter<float>("Render", "StarIntensity"); }
//            set { EffectMap.SetParameter<float>("Render", "StarIntensity", value); }
//        }
//        public Texture2D MieTexture
//        {
//            get { return EffectMap.GetParameter<Texture2D>("Render", "MieTexture"); }
//            set { EffectMap.SetParameter<Texture2D>("Render", "MieTexture", value); }
//        }
//        public Texture2D RayleighTexture
//        {
//            get { return EffectMap.GetParameter<Texture2D>("Render", "RayleighTexture"); }
//            set { EffectMap.SetParameter<Texture2D>("Render", "RayleighTexture", value); }
//        }
//        public Texture2D StarfieldTexture
//        {
//            get { return EffectMap.GetParameter<Texture2D>("Render", "StarfieldTexture"); }
//            set { EffectMap.SetParameter<Texture2D>("Render", "StarfieldTexture", value); }
//        }
//        public float Theta { get; set; }
//        public float Phi { get; set; }
//        public Vector3 Wavelength
//        {
//            get { return _waveLength; }
//            set
//            {
//                _waveLength = value;
//                Vector3 inverseWavelength = new Vector3();
//                inverseWavelength.X = 1.0f / (float)Math.Pow((double)_waveLength.X, 4.0);
//                inverseWavelength.Y = 1.0f / (float)Math.Pow((double)_waveLength.Y, 4.0);
//                inverseWavelength.Z = 1.0f / (float)Math.Pow((double)_waveLength.Z, 4.0);
//                Vector3 mieWavelength = new Vector3();
//                mieWavelength.X = (float)Math.Pow((double)_waveLength.X, -0.84);
//                mieWavelength.Y = (float)Math.Pow((double)_waveLength.Y, -0.84);
//                mieWavelength.Z = (float)Math.Pow((double)_waveLength.Z, -0.84);
//                InverseWavelength = inverseWavelength;
//                MieWavelength = mieWavelength;
//            }
//        }
//        public bool RealTime { get; set; }

//        public SkyDomeShader(string effectMap)
//            : base(effectMap)
//        {
//            Initialize();
//        }

//        public SkyDomeShader(EffectMap effectMap)
//            : base(effectMap)
//        {
//            Initialize();
//        }

//        public SkyDomeShader(string id, string effectMap)
//            : base(id, effectMap)
//        {
//            Initialize();
//        }

//        public SkyDomeShader(string id, EffectMap effectMap)
//            : base(id, effectMap)
//        {
//            Initialize();
//        }

//        private void Initialize()
//        {
//            _dome = new Dome(Engine.Instance, EffectMap.GetVariable<int>("Radius"), EffectMap.GetVariable<float>("Scale"));
//            _mieTarget = new RenderTarget2D(Engine.Instance.GraphicsDevice, 128, 64, 1, SurfaceFormat.HalfVector4, MultiSampleType.None, 0, RenderTargetUsage.DiscardContents);
//            _rayleighTarget = new RenderTarget2D(Engine.Instance.GraphicsDevice, 128, 64, 1, SurfaceFormat.HalfVector4, MultiSampleType.None, 0, RenderTargetUsage.DiscardContents);
//            _oldDepthBuffer = Engine.Instance.GraphicsDevice.DepthStencilBuffer;
//            _newDepthBuffer = new DepthStencilBuffer(Engine.Instance.GraphicsDevice,
//                Engine.Instance.GraphicsDevice.PresentationParameters.BackBufferWidth,
//                Engine.Instance.GraphicsDevice.PresentationParameters.BackBufferHeight,
//                Engine.Instance.GraphicsDevice.DepthStencilBuffer.Format,
//                MultiSampleType.None,
//                0);
//            Wavelength = EffectMap.GetVariable<Vector3>("Wavelength");
//            _quadRenderer = new QuadRenderer();
//            _quadRenderer.Initialize();
//            _quadRenderer.LoadContent();
//            _textureRenderer = new QuadRenderer(new VertexPositionTexture[]
//            {
//                new VertexPositionTexture(new Vector3(1,-1,0), new Vector2(1,1)),  
//                new VertexPositionTexture(new Vector3(-1,-1,0), new Vector2(0,1)),
//                new VertexPositionTexture(new Vector3(-1,1,0), new Vector2(0,0)),
//                new VertexPositionTexture(new Vector3(1,1,0), new Vector2(1,0))
//            });
//            _textureRenderer.Initialize();
//            _textureRenderer.LoadContent();
//            //_moonShader = new MoonShader(EffectMap.SubEffectMaps["Moon"]) { TextureRenderer = _textureRenderer };
//            //_perlinCloudsShader = new PerlinCloudsShader(EffectMap.SubEffectMaps["Clouds"]) { TextureRenderer = _textureRenderer };
//        }

//        #region Shader Members

//        public override void Draw(GameTime gameTime, SkyDomeShaderState state)
//        {
//            SunlightDirection = state.SunlightDirection.Inverse();

//            if (_previousTheta != Theta || _previousPhi != Phi)
//            {
//                Engine.Instance.GraphicsDevice.DepthStencilBuffer = _newDepthBuffer;
//                Engine.Instance.GraphicsDevice.SetRenderTarget(0, _rayleighTarget);
//                Engine.Instance.GraphicsDevice.SetRenderTarget(1, _mieTarget);
//                EffectMap.SetTechnique("Update");

//                foreach (EffectPass p in EffectMap.Begin())
//                {
//                    p.Begin();
//                    _quadRenderer.Draw(gameTime);
//                    p.End();
//                }

//                EffectMap.End();
//                Engine.Instance.GraphicsDevice.SetRenderTarget(1, null);
//                Engine.Instance.GraphicsDevice.SetRenderTarget(0, null);
//                MieTexture = _mieTarget.GetTexture();
//                RayleighTexture = _rayleighTarget.GetTexture();
//                Engine.Instance.GraphicsDevice.DepthStencilBuffer = _oldDepthBuffer;
//            }

//            Engine.Instance.GraphicsDevice.RenderState.DepthBufferEnable = false;
//            Engine.Instance.GraphicsDevice.RenderState.DepthBufferWriteEnable = false;
//            Engine.Instance.GraphicsDevice.Clear(Engine.Instance.FillColor);
//            Engine.Instance.GraphicsDevice.RenderState.CullMode = CullMode.CullClockwiseFace;
//            EffectMap.SetTechnique("Render");
//            //World = Matrix.CreateTranslation(Camera.ActiveCamera.Position);
//            //View = Camera.ActiveCamera.View;
//            //Projection = Camera.ActiveCamera.Projection;
//            WVP = Matrix.CreateTranslation(Camera.ActiveCamera.Position) * Camera.ActiveCamera.View * Camera.ActiveCamera.Projection;

//            if (Theta < Math.PI / 2.0f || Theta > 3.0f * Math.PI / 2.0f)
//            {
//                StarIntensity = (float)Math.Abs(Math.Sin(Theta + (float)Math.PI / 2.0f));
//            }
//            else
//            {
//                StarIntensity = 0;
//            }

//            foreach (EffectPass p in EffectMap.Begin())
//            {
//                p.Begin();
//                _dome.Draw();
//                p.End();
//            }

//            EffectMap.End();
//            state.Theta = Theta;
//            state.Phi = Phi;
//            _moonShader.Draw(gameTime, state);
//            Engine.Instance.GraphicsDevice.RenderState.CullMode = CullMode.CullCounterClockwiseFace;
//            _perlinCloudsShader.Draw(gameTime, state);
//            Engine.Instance.GraphicsDevice.RenderState.DepthBufferWriteEnable = true;
//            Engine.Instance.GraphicsDevice.RenderState.DepthBufferEnable = true;
//            _previousTheta = Theta;
//            _previousPhi = Phi;
//        }

//        #endregion
//    }
//}
